﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace iNet.Tasks
{
	/// <summary>
	/// 等待其他工作的 Task。
	/// </summary>
	public class JoinTask : Task
	{
		#region 欄位
		Task _TargetTask;
		#endregion
		#region 建構子
		/// <summary>
		/// 初始化新的 JoinTask 執行個體。
		/// </summary>
		/// <param name="targetTask">指定等待的工作。</param>
		/// <exception cref="ArgumentNullException">targetTask 為 Null (Visual Basic 為 Nothing)。</exception>
		public JoinTask(Task targetTask)
		{
			if (targetTask == null)
				throw new ArgumentNullException("targetTask");
			_TargetTask = targetTask;
		}
		#endregion
		#region Execute
		protected override bool Execute(TaskVersion version)
		{
			//啟動工作
			lock (_TargetTask.SyncRoot)
			{
				switch (_TargetTask.State)
				{
					case TaskState.Initializing:
						this.Executor.EnqueueTask(_TargetTask);
						break;
					case TaskState.Executed:
					case TaskState.Canceled:
						return true;
					case TaskState.Error:
						return false;
				}
			}

			//事件連結
			_TargetTask.MessageCreated += this.OnTargetTaskMessageCreated;

			//等待工作完成
			try
			{
				while (true)
				{
					//確認目標狀態
					switch (_TargetTask.State)
					{
						case TaskState.Executing:
							//回報進度
							this.ReportProgress(version, _TargetTask.Progress);

							//釋出執行緒資源
							if (_TargetTask.Executor == this.Executor && this.Executor.MaxThreads == 1)
								Task.Yield();
							else
								Thread.Sleep(100);
							break;
						case TaskState.Ready:
							//重設進度
							this.ReportProgress(version, null);

							//釋出執行緒資源
							if (_TargetTask.Executor == this.Executor && this.Executor.MaxThreads == 1)
								Task.Yield();
							else
								Thread.Sleep(100);
							break;
						case TaskState.Executed:
						case TaskState.Canceling:
						case TaskState.Canceled:
							return true;
						case TaskState.Initializing:
						case TaskState.Error:
							return false;
					}

					//確認是否已取消等待
					if (this.IsCanceling)
						return true;
				}
			}
			finally
			{
				//移除事件連結
				_TargetTask.MessageCreated -= this.OnTargetTaskMessageCreated;
			}
		}
		#endregion
		#region OnTargetTaskMessageCreated
		void OnTargetTaskMessageCreated(object sender, TaskMessageEventArgs e)
		{
			this.CreateMessage(this.CurrentVersion, e.MessageType, e.Message);
		}
		#endregion
		#region TargetTask
		/// <summary>
		/// 取得指定等待的工作。
		/// </summary>
		public Task TargetTask
		{
			get
			{
				return _TargetTask;
			}
		}
		#endregion
	}
}
